import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.Timer;
import javax.swing.JOptionPane;
import java.awt.Font;

public class gamePanel extends JPanel {
    int rows,cols,tntNum;
    public JPanel topPanel = new JPanel();
    public JButton ruleButton;
    static int snum;
    int timeLimit = -1;
    public boolean gameOver = false;
    public Cell[][] cells;
    //已标记的炸弹数量
    int flagedNum=0;
    //炸弹数量显示
    public JLabel tntLabel;
    //计时器
    Timer timer;
    //已使用时间
    static int timePassed = 0;
    //时间显示
    JLabel timeLabel;
    //提示按钮
    JButton promptButton;
    public gamePanel(int rows,int cols,int tntNum) {
        this.rows = rows;
        this.cols = cols;
        this.tntNum = tntNum;
        snum=tntNum;
        //布局
        this.setLayout(new BorderLayout());
        //上方顶部栏(实现重启、规则展示、展示炸弹数量、计时和提示功能)
        //JPanel topPanel = new JPanel();
        //重启 新开局(new)
        JButton remakeButton = new JButton("new");
        remakeButton.setFont(new Font("Arial",Font.PLAIN,16));//设置字体
        remakeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                remakeGame();
            }
        });
        topPanel.add(remakeButton);
        //规则显示 rule 点击后弹出游戏规则
        JButton ruleButton = new JButton("rule");
        ruleButton.setFont(new Font("Arial",Font.PLAIN,16));
        ruleButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                theRules();
            }
        });
        topPanel.add(ruleButton);
        //炸弹数量显示 标签
        tntLabel = new JLabel("Tnum:"+snum);
        tntLabel.setFont(new Font("Arial",Font.PLAIN,16));
        topPanel.add(tntLabel);
        //时间标签
        timeLabel = new JLabel("Time:"+timePassed);
        timeLabel.setFont(new Font("Arial",Font.PLAIN,16));
        topPanel.add(timeLabel);
        //提示按钮 前三分钟不可使用
        promptButton =new JButton("TS");
        promptButton.setFont(new Font("Arial",Font.PLAIN,16));
        promptButton.setEnabled(false);
        promptButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                providePromt();
            }
        });
        topPanel.add(promptButton);
        //将顶部栏加至北部
        this.add(topPanel, BorderLayout.NORTH);
        //中部:游戏区域
        //创建网格
        JPanel grid =new JPanel(new GridLayout(rows,cols));
        cells = new Cell[rows][cols];
        //创建每个小各自为按钮并加入grid中去
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                cells[i][j] = new Cell(i,j,this);
                grid.add(cells[i][j].button);
            }
        }
        this.add(grid, BorderLayout.CENTER);
        //设雷
        placeTnts();
        //计算雷数
        calculateTntnum();
        //启动计时器
        startTimer();
        //更新雷数
        updateTntNum();
    }
    public void remakeGame(){
        JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
        topFrame.dispose();
        mineSweeperFrame.showMenu();
    }
    public void providePromt(){
        for(int i = 0;i<rows;i++){
            for(int j = 0;j<cols;j++){
                Cell cell = cells[i][j];
                if(!(cell.Opened) && !(cell.isTnt) && !(cell.Flagged)){
                    cell.button.setBackground(Color.CYAN);
                    return;
                }
            }
        }
    }
    public void placeTnts() {
        Random rand = new Random();
        int num=0;
        while(num<tntNum){
            int r=rand.nextInt(rows);
            int c=rand.nextInt(cols);
            if(!cells[r][c].isTnt){
                cells[r][c].isTnt = true;
                num++;
            }
        }
    }
    public void calculateTntnum(){
        int[] dr={-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1,  0,  1, -1, 1, -1, 0, 1};
        for(int i = 0;i<rows;i++){
            for(int j = 0;j<cols;j++){
                //有地雷就跳过
                if(cells[i][j].isTnt){
                    continue;
                }
                int tntNum=0;
                //遍历八个方向
                for(int k = 0;k<dr.length;k++){
                    int ni=i+dr[k];
                    int nj=j+dc[k];
                    if(isBounds(ni,nj)&&cells[ni][nj].isTnt){
                        tntNum++;
                    }
                }
                cells[i][j].adjacentTnts = tntNum;
            }
        }
    }
    //new
    public void startTimer(){
        timer = new Timer(1000,new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timePassed++;
                timeLabel.setText("Time:" + timePassed + "s");

                if (timePassed >= 180 && (!promptButton.isEnabled())) {
                    promptButton.setEnabled(true);
                }
                if (timeLimit > 0 && timePassed >= timeLimit && !gameOver) {
                    gameOver = true;
                    stopTimer();
                    openAll();
                    JOptionPane.showMessageDialog(gamePanel.this,
                            "⌛限时已到！挑战失败！\n时间限制：" + timeLimit + " 秒",
                            "挑战失败",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        timer.start();
    }
    //判断行列用
    public boolean isBounds(int x, int y){
        return x>=0 && x<rows && y>=0 && y<cols;
    }
    public void openCell(int r,int c){
        Cell cell = cells[r][c];
        if(cell.Opened ||cell.Flagged){
            return ;
        }
        //cell.open();
        if(cell.isTnt){
            //选中地雷，gameover
            gameOver = true;
            //计时器停止
            stopTimer();
            //开启所有格子
            openAll();
            JOptionPane.showMessageDialog(this,
                    "💣「逻辑风暴吞噬观测者——第[■■]次因果律回溯失败，雷核于‘认知盲区’绽放赤狱之花。\n" +
                            "解构小队，汝等的灵魂数据…已成为渊薮悲鸣的[第9,999,997份样本]。」\n" +
                            "用时: " + timePassed + "秒",
                    "游戏结束",
                    JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        if(cell.adjacentTnts == 0){
            openEmpty(r, c);
        }else{
            //如果周边有雷，就只打开这一个格子
            cell.open();
        }
        //每次开格子后检测游戏是否取胜
        checkWin();
    }
    public void stopTimer(){
        timer.stop();
    }
    public void openAll(){
            for (int i = 0; i < cells.length; i++) {
                for (int j = 0; j < cells[i].length; j++) {
                    Cell cell = cells[i][j];
                    cell.open();
                }
            }
        }
    public void openEmpty(int r,int c){
        if(!isBounds(r,c) ||cells[r][c].Opened ||cells[r][c].isTnt){
            return;
        }
        cells[r][c].open();
        if(cells[r][c].adjacentTnts != 0){
            return;
        }
        int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1,  0,  1, -1, 1, -1, 0, 1};
        for (int i = 0; i < 8; i++) {
            openEmpty(r + dr[i], c + dc[i]);
        }
    }
    public void checkWin(){
        for(Cell[] row:cells){
            for(Cell cell:row){
                if(!(cell.isTnt) &&!(cell.Opened)){
                    return;
                }
            }
        }
        gameOver = true;
        stopTimer();
        openAll();
        JOptionPane.showMessageDialog(this,
                "🎉「认知重构完成——虚数雷网熵值归零，悲鸣锁链崩解为星尘。\n" +
                        "汝等以血肉之躯拼合‘世界之骸’的最后一枚碎片，此刻，寂灭的权柄…由解构者篡夺。」\n" +
                        "用时: " + timePassed + " 秒",
                "胜利",
                JOptionPane.INFORMATION_MESSAGE);

    }
    public void updateTntNum(){
        flagedNum=0;
        for(Cell[] row:cells){
            for(Cell cell:row){
                if(cell.Flagged){
                    flagedNum++;
                }
            }
        }
        snum=tntNum-flagedNum;
        if(snum<0){
            snum=0;
        }
        tntLabel.setText("Tnum: "+snum);
    }
    public void theRules(){
        String rules = "扫雷游戏规则:\n"
                + "1. 游戏开始时，所有方格都是隐藏状态。\n"
                + "2. 左键点击一个方格：\n"
                + "   ①如果该格是地雷，游戏结束。\n"
                + "   ②如果该格不是地雷，显示该格周围 8 个方向的地雷数量。\n"
                + "   ③如果周围地雷数为 0，则自动展开相邻格。\n"
                + "3. 右键点击格子可以标记或取消标记为旗子（F）。\n"
                + "4. 当所有非雷格子都被揭示时，视为游戏胜利。\n"
                + "5. 游戏上方的按钮new为重新开始，TS为提示（提示在前三分钟内不可使用），rule为游戏规则也就是此界面。";
        JOptionPane.showMessageDialog(this, rules, "游戏规则", JOptionPane.INFORMATION_MESSAGE);
    }
    public void setTimeLimit(int seconds) {
        this.timeLimit = seconds;
    }
    public JPanel getTopPanel() {
        return topPanel;
    }
}
